var md5 = require("md5");
var js2xml = require("js2xmlparser");
var xml2js = require("xml2js");

exports.createNonceStr = function () {
  return Math.random().toString(36).substr(2, 15);
};

exports.createTimestamp = function () {
  return parseInt(new Date().getTime() / 1000) + '';
};

var raw = function (args) {
  var keys = Object.keys(args);
  keys = keys.sort()
  var newArgs = {};
  keys.forEach(function (key) {
    newArgs[key.toLowerCase()] = args[key];
  });

  var string = '';
  for (var k in newArgs) {
    string += '&' + k + '=' + newArgs[k];
  }
  string = string.substr(1);
  return string;
};

/**
* @synopsis 签名算法 
*
* @param jsapi_ticket 用于签名的 jsapi_ticket
* @param url 用于签名的 url ，注意必须动态获取，不能 hardcode
*
* @returns
*/
exports.get_ticket_sign = function (jsapi_ticket, url) {
  var ret = {
    jsapi_ticket: jsapi_ticket,
    nonceStr: createNonceStr(),
    timestamp: createTimestamp(),
    url: url
  };
  var string = raw(ret);
  jsSHA = require('jssha');
  shaObj = new jsSHA(string, 'TEXT');
  ret.signature = shaObj.getHash('SHA-1', 'HEX');

  return ret;
};

//由对象生成xml文件
exports.convert_obj_to_xml = function(item){
	var xml_str = js2xml("xml",item);
	return xml_str;
};

//将查询订单返回的XML对象转化为普通的JSON对象
var clear_xml_obj = function(xml_obj){
	var item = {};
	Object.keys(xml_obj.xml).forEach(function(key,index){
		item[key] = xml_obj.xml[key][0];
	});
	return item;
};

//将XML字符串转化为JS对象
exports.convert_xml_to_obj = function(xml_str){
	var obj = {};
	xml2js.parseString(xml_str,function(err,result){
		if(!err) obj = result;
	});	
	return clear_xml_obj(obj);
};

/**
 *支付接口都需要为字段生成签名(sign)，具体步骤如下：
 *1) 将所接受的数据键值按ASSIC码排序，使用URL键值对拼接成字符串
 *2) 字符串最后接上支付密钥并进行MD5运算，并转化为大写
 *@param {item} 要生成签名的对象，会将对象的属性组合成{key=value&key2=value2}的方式
 *@param {partner_key} 微信商户中API密钥
 *@returns 生成的签名
 */
exports.generate_pay_sign = function(item,partner_key){
	var str = Object.keys(item).filter(function(key){
		if( item[key] !== undefined && item[key] !== "")
			return item[key];
	}).sort().map(function(key){
		return key+"="+item[key];
	}).join("&");
	str = str + "&key=" + partner_key;
	return md5(str).toUpperCase();
};
